約 3,331,694 件
https://w.atwiki.jp/enetu/pages/20.html
FEZ動画データベースzunz http //zunz.x0.to/ PSを上達する上でうまい人の動画を見ることはとても有効です。 @
https://w.atwiki.jp/a3mi22/pages/80.html
リポジトリ データや情報などが保管されている場所。 アプリケーションやシステムの設定情報がまとめて記録されているファイルやフォルダのこと。 複数の開発者が参加するプログラミング環境においてソースコードや仕様に関する情報をまとめて保管してくれるシステムなど。 合計: -
https://w.atwiki.jp/qururu/pages/12.html
Oracle物理データベース構造 Oracleデータベースは、次の物理データベース構造で構成されている。 データファイル データベースに格納する全てのデータが含まれる。 表や索引などの論理構造の内容は、データファイルに物理的に格納される。 制御ファイル データベースのファイル配置など物理構造を指定するエントリが含まれる。 REDOログファイル データに対して行われた全ての変更を記録する。 小見出し
https://w.atwiki.jp/tenga18/pages/131.html
適当にデータ残していくぞぃ +アクション系 TA記録 +アスカ アスカ部記録 +ラジオ 獄卒1周年記念ラジオ 獄卒2周年記念ラジオ
https://w.atwiki.jp/liicaq2wiki/pages/68.html
このページは各ロードの一覧ページです。 鍵・人間性一覧データベースと一緒に確認すれば全人間性獲得できます、多分。 ロード・領域とは何かの解説ページ→エリアの種類について + 目次 ALPHA 5領域 EPSILON 4領域 ALPHA 9領域 EPSILON 16領域 EPSILON 13ロード BETA 1ロード ZETA 4領域 BETA 13ロード ZETA 12領域 GAMMA 5ロード ETA 14ロード 裏ETA 16領域 裏DELTA 16領域 裏ZETA 16領域 裏GAMMA 16領域 裏EPSILON 16領域 裏BETA 16領域 裏ALPHA 16領域 裏PRIMARY 8最終ロード ALPHA 5領域 順序 ステージ名 備考 PRIMARY 8クリアで開放 1 ALPHA 5 2 ALPHA 6 3 ALPHA 1 4 ALPHA 2 EPSILON 4領域 順序 ステージ名 備考 PRIMARY 13クリアで開放 1 EPSILON 4 2 EPSILON 3 EPSILON 7 EPSILON 8 ALPHA 9領域 順序 ステージ名 備考 SECONDARY 4クリアで開放 1 ALPHA 9 2 ALPHA 10 ALPHA 13 EPSILON 16領域 順序 ステージ名 備考 SECONDARY 5クリアで開放 1 EPSILON 16 2 EPSILON 15 3 EPSILON 11 4 EPSILON 12 EPSILON 13ロード めっちゃ長いロード。 順序 ステージ名 備考 SECONDARY 13クリアで開放 1 EPSILON 13 2 EPSILON 14 3 EPSILON 10 4 EPSILON 9 5 ZETA 2 6 ZETA 6 7 ZETA 10 8 ZETA 14 9 ETA 16 10 ETA 12 11 ETA 8 12 ETA 4 13 ZETA 13 14 ZETA 9 15 ZETA 5 16 ZETA 1 17 ETA 2 18 ETA 1 19 EPSILON 5 20 EPSILON 6 21 EPSILON 2 22 EPSILON 1 23 ALPHA 16 24 ALPHA 12 25 ALPHA 8 26 ALPHA 4 27 ALPHA 3 28 ALPHA 7 29 ALPHA 11 30 ALPHA 15 31 ALPHA 14 BETA 8 32 BETA 7 BETA 8クリアで開放 33 BETA 5 BETA 6 BETA 9 BETA 10 BETA 11 BETA 12 34 GAMMA 9 BETA 12クリアで開放 35 GAMMA 13 36 GAMMA 14 37 GAMMA 15 38 GAMMA 16 39 GAMMA 12 40 DELTA 16 41 DELTA 11 DELTA 12 DELTA 15 BETA 1ロード 順序 ステージ名 備考 SECONDARY 16クリアで開放 1 BETA 1 2 BETA 2 3 BETA 3 4 BETA 4 5 DELTA 4 6 DELTA 3 DELTA 7 DELTA 8 ZETA 4領域 順序 ステージ名 備考 TERTIARY 5クリアで開放 1 ZETA 3 ZETA 4 ZETA 7 ZETA 8 BETA 13ロード 順序 ステージ名 備考 TERTIARY 8クリアで開放 1 BETA 13 2 BETA 14 3 BETA 15 4 BETA 16 5 DELTA 1 6 DELTA 2 DELTA 5 DELTA 6 ZETA 12領域 順序 ステージ名 備考 QUATERNARY 5クリアで開放 1 ZETA 11 ZETA 12 ZETA 15 ZETA 16 GAMMA 5ロード 順序 ステージ名 備考 QUATERNARY 8クリアで開放 1 GAMMA 5 2 GAMMA 1 3 GAMMA 2 4 GAMMA 3 5 GAMMA 4 6 GAMMA 8 7 DELTA 13 8 DELTA 9 DELTA 10 DELTA 14 ETA 14ロード 順序 ステージ名 備考 QUINARY 5クリアで開放 1 ETA 14 2 ETA 5 ETA 6 ETA 7 ETA 9 ETA 10 ETA 11 ETA 13 ETA 15 3 GAMMA 6 ETA 15クリアで開放 GAMMA 7 GAMMA 10 GAMMA 11 4 ETA 3 上記四問クリアで開放 裏ETA 16領域 裏QUINARY 9クリアで開放 裏ETA前半全問 裏DELTA 16領域 裏QUINARY 4クリアで開放 裏DELTA前半全問 裏ZETA 16領域 裏QUATERNARY 9クリアで開放 裏ZETA前半全問 裏GAMMA 16領域 裏QUATERNARY 4クリアで開放 裏GAMMA前半全問 裏EPSILON 16領域 裏TTERTIARY 9クリアで開放 裏EPSILON前半全問 裏BETA 16領域 裏TERTIARY 4クリアで開放 裏BETA前半全問 裏ALPHA 16領域 裏SECONDARY 12クリアで開放 裏ALPHA前半全問 裏PRIMARY 8最終ロード 最終ステージにつながる、最後のロード。 順序 ステージ名 備考 裏PRIMARY 前半5問クリアで開放 1 裏PRIMARY 8 2 裏PRIMARY 7 3 裏PRIMARY 6 4 裏PRIMARY 5 5 裏PRIMARY 4 6 裏PRIMARY 3 7 裏PRIMARY 2 8 裏ALPHA 後半全問 9 裏EPSILON 後半全問 裏ALPHA後半5問クリアで開放 10 裏BETA 後半全問 裏EPSILON後半5問クリアで開放 11 裏ZETA 後半全問 裏BETA後半5問クリアで開放 12 裏GAMMA 後半全問 裏ZETA後半5問クリアで開放 13 裏ETA 後半全問 裏GAMMA後半5問クリアで開放 14 裏DELTA 後半全問 裏ETA後半5問クリアで開放 15 裏PRIMARY 1 裏ETA 3クリアで開放(※) 16 PRIMARY 0 ※クリアには裏DELTAにある鍵を獲得しなければならないため、実質15番目の開放
https://w.atwiki.jp/fwchronicle/pages/184.html
GMのもろもろのデータを集めておく場所です。 進行中のキャンペーン、オムニバス依頼、その他もろもろありましたら、オープンソースとして利用してください。 GM名 じぇーん(GぇM) しろん(しろいひと) yuu(GM@不定) 666(GM.NO666)
https://w.atwiki.jp/nouryoku/pages/2570.html
『学園』とガーデンの為のデータベースである。 ガーデンの情報は基本的に秘匿される方向の為、ガーデンの情報はガーデンの所属のみにしか明かされない。 故に、使えるフォームも、変わる事となる。 学園の情報は公開されているため、学園の連絡は一般人でも見ることが出来る。 運動会や、イベントの告知を此処ですることもあるだろう。 『学園掲示板』 学園の情報は公開のため、一般人も書き込み可 名前 コメント 『ガーデン所属限定』 ガーデンに所属するもの以外は書き込みも閲覧も不可 名前 コメント
https://w.atwiki.jp/setechdiv/pages/26.html
データ連携について 固定長CSVで30列と決まって入ってくるデータがあったとして、 Access側で必ずしも30列用意して受け入れなければならないわけではない 行列を入れ替えたり、Nullであるデータを省いたりも出来るのである。 最終的に何がしたいか、を考えて設計すべき。
https://w.atwiki.jp/nsota/pages/23.html
大阪湾リアルタイムデータ http //kouwan.pa.kkr.mlit.go.jp/kankyo-db/ の大阪湾水質定点自動観測データ配信システムバナー
https://w.atwiki.jp/opentfc/pages/117.html
## Time-stamp 2011-12-16 Fri 14 49 08 JST 3.1 CDとレコード 3.2 CDのリファイリング 3.3 データベースの中身を見てみる 3.4 ユーザインタラクションを改善する 3.5 データベースの保存と読み出し 3.6 データベースにクエリを投げる 3.7 既存のレコードを更新する(もう1つのwhereの使い道) 3.8 ムダを排除して勝利を収める CDとレコード CDのタイトル、アーティスト名、レート、リッピング済みかなどの情報をレコードに持たせる。 ここではリストを使ったデータ構造で。 属性リスト(Property list plist)を使う。 要素を説明するシンボルとその要素が、先頭から順に交互に並んでいるリスト。 CL-USER (list a 1 b 2 c 3) ( A 1 B 2 C 3) 属性リストはgetf関数が使える。 getf関数は、属性リストとシンボルを1つずつ取り、 属性リストの中のシンボルの次にある値を返す。 ハッシュっぽいやつ。 CL-USER (getf (list a 1 b 2 c 3) a) 1 4つのフィールドを引数にとってCDを表す属性リストを返す関数make-cd (defun make-cd (title artist rating ripped) (list title title artist artist rating rating ripped ripped)) CL-USER (make-cd "Roses" "Kathy Mattea" 7 t) ( TITLE "Roses" ARTIST "Kathy Mattea" RATING 7 RIPPED T) CDのファイリング 複数のレコードを保持する。 グローバル変数*db*を使う。 グローバル変数の前後にアスタリスクをつけるのはLisp界隈のならわし。 (defvar *db* nil) 「*db*」に要素を加えるにはpushマクロが使える。 抽象化のためにadd-record関数を追加。 CL-USER (add-record (make-cd "Roses" "Kathy Mattea" 7 t)) (( TITLE "Roses" ARTIST "Kathy Mattea" RATING 7 RIPPED T)) CL-USER (add-record (make-cd "Fly" "Dixie Chicks" 8 t)) (( TITLE "Fly" ARTIST "Dixie Chicks" RATING 8 RIPPED T) ( TITLE "Roses" ARTIST "Kathy Mattea" RATING 7 RIPPED T)) pushは変更した変数の更新後の値を返す。 データベースの中身を見てみる 「*db*」を見やすくする。 データベースの内容をダンプする関数dump-db。 (defun dump-db () (dolist (cd *db*) (format t "~{~a ~10t~a~%~}~%" cd))) format関数についてはどっかでまとめる。 ユーザインタラクションを改善する add-recordでもレコードの追加はできるけど、普通のユーザにはLispくさすぎる。 また大量に登録するには向いていない。 情報の入力を促して結果を読み込む手段がいる。 (defun prompt-read (prompt) (format *query-io* "~a " prompt) (force-output *query-io*) (read-line *query-io*)) ストリーム*query-io*にpromptをフォーマットして出力。 force-outputで改行コードを待つことなくプロンプトが印字されるように保証。 テキストを1行読み込む関数read-lineで、 端末に接続された入力ストリーム*query-io*を読み込んで、 read-lineは改行文字を含まない*query-io*(文字列)を返す。 値を次々に入力してCDレコードを作るには、make-cdとprompt-readを組み合わせる (defun prompt-for-cd () (make-cd (prompt-read "Title") (prompt-read "Artist") (prompt-read "Rating") (prompt-read "Ripped [y/n] "))) prompt-readが返すのは文字列だから、文字列以外を返してほしい部分を書き換える。 parse-integer関数でRatingを数にする。 (parse-integer (prompt-read "Rating")) parse-integerはデフォルトでは、文字列に数以外が入っていたらエラーになるからオプションをつける。 オプション junk-allowedを使ってエラーにならないようにする。 エラーの代わりにnilが返ってくるが、0が返ってくるように変更する。 (or (parse-integer (prompt-read "Rating") junk-allowed t) 0) Rippedの部分は、y/nのブール値を入れるようにする。 (y-or-n-p "Ripped [y/n] ") yかnを入れないと再入力を要求する。 大量にデータを入力するためにループさせる。 loopマクロを使う。 loopマクロはreturnが呼び出されるまで繰り返し実行するもの。 (defun add-cds () (loop (add-record (prompt-for-cd)) (if (not (y-or-n-p "Another? [y/n] ")) (return)))) データベースの保存と読み出し 保存 登録したデータベースのレコードを保存する関数save-db。 ファイル名を引数に取り、現在のデータベースの状態を保存する。 (defun save-db (filename) (with-open-file (out filename direction output if-exists supersede) (with-standard-io-syntax (print *db* out)))) with-open-fileマクロはfilenameに対応するファイルをオープンし、 それに対応するストリームを変数outに束縛し、 一連の式の評価が終わったらファイルをクローズする。 途中でよくないことが起きてもクローズしてくれる。 「 direction output」で書き込みモード、 「 if-exists supersede」で同じ名前のファイルが存在したら上書きすることを指定。 ファイルを開いたら(print *db* out)で印字。 printはLispオブジェクトを再度読み取り可能な形で出力。 with-standard-io-syntaxマクロは、標準化した出力にしてくれる。(処理系の違いを気にしなくてよくなる) 読み出し データベースを読み戻すための関数load-db。 (defun load-db (filename) (with-open-file (in filename) (with-standard-io-syntax (setf *db* (read in))))) with-open-fileマクロの directionはデフォルトで inputなっている。 印字する代わりにread関数でストリームinから読み込む。 db*が上書きされるのに注意。 データベースにクエリを投げる データベースに追加したり読みだしたりする機能はつけたけど、 いちいち全部のデータベースを読み込まないといけないから、 こんな機能があったらいい。 (select artist "Dixie Chicks") これでアーティスト名がDixie Chicksになっているレコードのリストを取得する。 remove-if-not関数 CL-USER (remove-if-not # evenp (1 2 3 4 5 6 7 8 9 10)) (2 4 6 8 10) 述語とリストを引数にとって、元のリストから述語が真となる要素だけを含むリストを返す。 述語でなく、ラムダ式を渡すこともできる。 evenpという関数が無かったらなかったら、 CL-USER (remove-if-not # (lambda (x) (= 0 (mod x 2))) (1 2 3 4 5 6 7 8 9 10)) (2 4 6 8 1) アーティスト名にマッチするレコードを取り出す。 入力したアーティスト名にマッチしたら真を返す関数がいる。 レコードを表現するのに属性リストを使っているから、 getf関数が使える。 データベース内のある1つのレコードを保持する変数をcdとする。 cdの artistに対応する要素を(getf cd artist)で取る。 equal式でラムダ式で引数のartistと、cdの artistに対応する要素が等しいか見る。 (defun select-by-artist (artist) (remove-if-not # (lambda (cd) (equal artist (getf cd artist))) *db*)) アーティスト名での検索以外にもtitleとか,ratingとかでの検索が欲しくなる。 これらはラムダ式以外は同一の関数になるだろうから, 関数selectを使って一般化する。 (defun select (selector-fn) (remove-if-not selector-fn *db*)) remove-if-notに変数selector-fnに束縛されたラムダ式を渡すから「# 」はいらない。 select関数を呼び出すときに「# 」が必要。 関数selectに渡すラムダ式をラッピングする。 (defun artist-selector (artist) # (lambda (cd) (equal (getf cd artist) artist))) 関数artist-selectorはある関数を返す。 帰ってくる関数が参照してる変数は,関数artist-selectorが返った時点では 存在していないように見えるかもしれないが,ちゃんと動く。 このような関数を閉包(クロージャ)と呼ぶ。 「"Dixie Chicks"」を引数にしてartist-selectorを呼び出せば, CDの artistがDixie Chicksと同じかどうかを調べるラムダ式が得られる。 CL-USER (select (artist-selector "Dixie Chicks")) (( TITLE "Fly" ARTIST "Dixie Chicks" RATING 8 RIPPED T) ( TITLE "Home" ARTIST "Dixie Chicks" RATING 9 RIPPED T)) 他のフィールドについてもセレクタを生成する関数が必要。 似たようなセレクタ関数生成器を何度も書くのは避けたいから,汎用のセレクタ関数生成器を書く。 与えられた引数に応じて各フィールドに対応したセレクタ関数を生成したり, フィールドの組み合わせに対応したセレクタ関数を生成する関数をつくる。 そのためにキーワードパラメータという機能について学ぶ。 引数の数を固定せずに呼び出せる関数を作れる。 普通の関数 CL-USER (defun foo (a b c) (list a b c)) FOO CL-USER (foo 1 2 3) (1 2 3) キーワードパラメータを使った関数 CL-USER (defun foo ( key a b c) (list a b c)) FOO CL-USER (foo c 3 a 1 b 2) (1 2 3) CL-USER (foo a 1 c 3) (1 NIL 3) CL-USER (foo) (NIL NIL NIL) 変数a, b, cの値は対応するキーワードに続く値に束縛される。 デフォルト値はデフォルトではnilだが,これではnilをパラメータに渡したのと区別がつかない。 これを区別するためにsupplied-pパラメータを使う。 (defun foo ( key a (b 20) (c 30 c-p)) (list a b c c-p)) 上記ではbのデフォルト値は20,cのデフォルト値は30で,変数c-pがsupplied-pパラメータである。 cに値が渡されたら真,値が渡されなければ偽となる。 CL-USER (foo c 3 a 1 b 2) (1 2 3 T) CL-USER (foo a 1 c 3) (1 20 3 T) CL-USER (foo) (NIL 20 30 NIL) 汎用セレクタ関数生成器 whereという名前で作る。 CDレコードの各フィールドに対応する4つのキーワードパラメータをとり, whereが呼び出されたときに指定された全ての値と一致するCDを選び出すセレクタ関数を作り出す。 (defun where ( key title artist rating (ripped nil ripped-p)) # (lambda (cd) (and (if title (equal (getf cd title) title) t) (if artist (equal (getf cd artist) artist) t) (if rating (equal (getf cd rating) rating) t) (if ripped-p (equal (getf cd ripped) ripped) t)))) この関数はCDレコードのフィールドごとに定義された条件式のANDを返す無名関数を値として返す。 それぞれの条件式は,引数にnil以外の値が渡されていたら, その引数がCDレコードのフィールド値と一致するかどうかを値とし, そうでなければ真を返す。 対応するパラメータが渡されなければ,条件式は真となるから, 生成されるセレクタ関数はwhereに与えられたすべての引数と一致するCDだけを選び出せる。 フィールドrippedについては,「rippedの値がnilのCDを選べ」なのか, 「rippedの値は考慮しない」という意味でrippedの値を指定していないのかを区別できるようにしている。 動作例 CL-USER (select (where rating 8 ripped t)) (( TITLE "Fly" ARTIST "Dixie Chicks" RATING 8 RIPPED T)) CL-USER (select (where artist "Dixie Chicks")) (( TITLE "Fly" ARTIST "Dixie Chicks" RATING 8 RIPPED T) ( TITLE "Home" ARTIST "Dixie Chicks" RATING 9 RIPPED T)) 既存のレコードを更新する(もう一つのwhereの使い道) データベースであれば備えられている機能,レコードの更新機能を実現する。 SQLではwhere句に一致するレコードをまとめて更新するためにupdate文がある。 update文は更新したいレコードを選択するセレクタ関数と, 変更したい値をキーワード引数を使ってにして指定すればいい。 mapcar関数を使う。 mapcar関数は,あるリストに含まれる全ての要素について関数を適用した結果を集めた新しいリストを返す。 #+BEGIN_SRC common-lisp (defun update (selector-fn key title artist rating (ripped nil ripped-p)) (setf *db* (mapcar # (lambda (row) (when (funcall selector-fn row) (if title (setf (getf row title) title)) (if artist (setf (getf row artist) artist)) (if rating (setf (getf row rating) rating)) (if ripped-p (setf (getf row ripped) ripped))) row) *db*))) #+END_SRC setfは変数にだけじゃなく,「場所」に代入するのにも使えるものだと解釈しておく。 update関数でDixie Chicksのすべてのアルバムのレートを11に変える例を示す。 #+BEGIN_EXAMPLE CL-USER (update (where artist "Dixie Chicks") rating 11) #+END_EXAMPLE データベースからレコードを削除するための関数は簡単に作れる。 #+BEGIN_SRC common-lisp (defun delete-row (selector-fn) (setf *db* (remove-if selector-fn *db*))) #+END_SRC remove-if関数はremove-if-not関数の反対。 引数にとったリストから,条件式にマッチした要素を全て削除したリストを返す。 元のリストに変更を加えるわけではないため,setfで*db*に戻り値を保存している。 ムダを排除して勝利を収める マクロを使って,これまで作った関数の無駄な重複を取り除く。 無駄はwhere関数にある。 各フィールドごとに #+BEGIN_SRC (if title (equal (getf cd title) title) t) #+END_SRC のような式を評価している。 title以外のフィールドの値のチェックのときも,いちいちtitleが入っているかチェックしている。 必要以上のチェックをしている。 無駄を省くとしたら, #+BEGIN_SRC CL-USER (select (where title "Give Us a Break" ripped t)) #+END_SRC は以下のように変更できる。 #+BEGIN_SRC CL-USER (select # (lambda (cd) (and (equal (getf cd title) "Give Us a Break") (equal (getf cd ripped) t)))) #+END_SRC このラムダ式はwhereが返すものとは違うものを返す。 効率のいいセレクタ関数を返すように意図している。 これをマクロを使って書く。 マクロ マクロは式を作る式。 マクロで作られた式をREPLが評価することで結果が返る。 簡単な例をやる。 reverse関数は引数に1つのリストをとり,そのリストの順序を反転したリストを返す関数。 backwardsというマクロを定義する。 マクロの定義は,defmacroに続けて名前,パラメータリスト,本体の式からなる。 #+BEGIN_SRC CL-USER (defmacro backwards (expr) (reverse expr)) BACKWARDS CL-USER (backwards ("hello, world" t format)) hello, world NIL #+END_SRC 動作を説明する。 - REPLがbackwardsがマクロの名前であることを認識する。 - 式("hello, world" t format)は評価されずに放っておかれる。 - backwordsの中でリストはreverseに渡され (format t "hello, world") というリストがREPLに返される。 - REPLが (format t "hello, world") を評価する。 マクロの動作おいて動作効率はまったく同じになる。 マクロを使ってwhereを改良する もともとのwhereには各フィールドに対して以下の式があった。 #+BEGIN_SRC (equal (getf cd field) value) #+END_SRC フィールドと値を受け取り上記の式を返す関数を書いてみる。 式は単なるリストだから以下のようにできると思うかもしれない。 #+BEGIN_SRC ;; 間違い (defun make-comparison-expr (field value) (list equal (list getf cd field) value)) #+END_SRC これでは,equal, getf, cd, field, valueが評価される。 fieldとvalueは期待した動作であるが,equal, getf, cdは違う。 しかし,Lispはシングルクォート「 」を評価させたくないものの前につけることで, 評価をやめさせることができる。 以下のように書けば,期待した動作をする。 #+BEGIN_SRC (defun make-comparison-expr (field value) (list equal (list getf cd field) value)) #+END_SRC #+BEGIN_EXAMPLE CL-USER (make-comparison-expr rating 10) (EQUAL (GETF CD RATING) 10) CL-USER (make-comparison-expr title "Give Us a Break") (EQUAL (GETF CD TITLE) "Give Us a Break") #+END_EXAMPLE さらにいい方法 「大半は評価されたくないけど,その中から特に評価させたい式だけを選び出して評価させることができる」ような式を書く。 バッククォート「`」を式の前に置くと,その式は評価されなくなる。 バッククォートが置かれた式の中で評価させたいものには,コンマ「,」を置く。 #+BEGIN_EXAMPLE CL-USER `(+ 1 2 3) (+ 1 2 3) CL-USER `(+ 1 2 (+ 1 2)) (+ 1 2 (+ 1 2)) CL-USER `(+ 1 2 ,(+ 1 2)) (+ 1 2 3) #+END_EXAMPLE これを使って関数make-comparison-exprを書き換える #+BEGIN_SRC (defun make-comparison-expr (field value) `(equal (getf cd ,field) ,value)) #+END_SRC セレクタ関数はフィールドと値のペア1個につき比較を行う式が1つあり,それらがandで包まれている。 whereマクロに渡す引数は単一のリストとして用意することにして, それぞれのペアに対してmake-comparison-exprを呼び出した結果を集める関数を作る。 loopを使う。 #+BEGIN_SRC (defun make-comparisons-list (fields) (loop while fields collecting (make-comparison-expr (pop fields) (pop fields)))) #+END_SRC 「while fields」はfieldsに要素が残っている間はループするという意味。 1回のループで2回のpopによりfieldsから2つの要素を取り出し, それらにmake-comparison-exprを適用する。 その結果を集めて(collecting),ループが終わったときの結果として返す。 最後にmake-comparisons-listから返されるリストをANDで包んでラムダ式に入れ込めばいい。 #+BEGIN_SRC (defmacro where ( rest clauses) `# (lambda (cd) (and ,@(make-comparisons-list clauses)))) #+END_SRC 「,@」は,@以降の式と,@を囲んでいる式を結合する。 #+BEGIN_EXAMPLE CL-USER `(and ,(list 1 2 3)) (AND (1 2 3)) CL-USER `(and ,@(list 1 2 3)) (AND 1 2 3) CL-USER `(and ,@(list 1 2 3) 4) (AND 1 2 3 4) #+END_EXAMPLE 「 rest」が引数リストにあると,関数やマクロは任意個の引数を取ることができ, 引数が1つのリストにまとめられたものが restの後の名前の変数の値になる。(ここではclauses) whereを #+BEGIN_EXAMPLE (where title "Give Us a Break" ripped t) #+END_EXAMPLE と呼ぶと,clausesの値は以下となる。 #+BEGIN_EXAMPLE ( title "Give Us a Break" ripped t) #+END_EXAMPLE マクロ展開の値を確認 関数macroexpand-1を使う。 macroexpand-1にマクロ呼び出しのフォームを渡すと, 展開されたものが返る。 #+BEGIN_EXAMPLE CL-USER (macroexpand-1 (where title "Give Us a Break" ripped t)) # (LAMBDA (CD) (AND (EQUAL (GETF CD TITLE) "Give Us a Break") (EQUAL (GETF CD RIPPED) T))) T #+END_EXAMPLE